#pragma once
#include<iostream>
#include<unistd.h>
#include<vector>
#include <sys/wait.h>
#include <functional>
#include<time.h>
#include"Task.hpp"
#include"Channel.hpp"

class processpool
{
    public:
    processpool(int n=0):_n(n)
    {
        //进程初始化
        //子进程读
        for(int i=0; i<n; i++)
        {
            int pipefd[2];
            if(pipe(pipefd)==-1)
            {
                std::cerr<<"pipe(pipefd):"<<std::endl;
                exit(2);//进程退出
            }

            pid_t fd=fork();
            if(fd==-1)
            {
                std::cerr<<"pid_t fd=fork();:"<<std::endl;
                exit(3);
            }

            if(fd==0)
            {
                //child
                ::close(pipefd[1]);
                //标准输入也改为匿名通道,方便后序读取内容
                dup2(pipefd[0],0);
                
                Work();
            }

            //father
            ::close(pipefd[0]);
            channels.emplace_back(fd,pipefd[1]);
        }
    }

    ~processpool()
    {
        // for(auto e:channels)
        // {
        //     e.close();
        //     int n=::waitpid(e.id(),nullptr,0);
        //     if(n==-1)
        //     {
        //         std::cerr<<"等待错误"<<std::endl;
        //     }
        //     std::cout<<"等待"<< e.id()<<"进程完成"<<std::endl;
        // }
        //1.从后往前释放2.加载进程前提前关闭文件
        for(auto e:channels)
        {
            e.close();
        }
        
        for(auto e:channels)
        {
            int n=::waitpid(e.id(),nullptr,0);
            if(n==-1)
            {
                std::cerr<<"等待错误"<<std::endl;
            }
            std::cout<<"等待"<< e.id()<<"进程完成"<<std::endl;
        }


        std::cout<<"进程池清理完毕"<<std::endl;
    }

    void AssignTask()
    {
        int who=0;//轮循下标
        int num=20;

        while(num--)
        {
            who++;
            who=who%_n;

            Task task;
            channels[who].send(task.slectNum());
        }
    }

    private:
    int _n;//进程个数
    std::vector<channel> channels;//子进程数组
};